home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v8n21.arc / MPDIV.ASM < prev    next >
Assembly Source File  |  1989-11-11  |  5KB  |  132 lines

  1.         title   MPDIV.ASM Multiple-Precision Unsigned Divide
  2.         page    55,132
  3.  
  4. ; MPDIV.ASM     Multiple-Precision Unsigned Divide
  5. ;               using "shift-and-subtract" method
  6. ;               for Intel 8086, 8088, 80286, and
  7. ;               80386 in real mode/16-bit protected mode.
  8. ;
  9. ; Copyright (c) 1989 Ziff Davis Communications
  10. ; PC Magazine * Ray Duncan
  11. ;
  12. ; Call with:    DS:SI   = address of divisor
  13. ;               ES:DI   = address of dividend
  14. ;               CX      = divisor length in bytes
  15. ;                         (dividend length = 2 * divisor length)
  16. ;
  17. ;               Assumes direction flag is clear at entry
  18. ;               Assumes DS = ES <> SS
  19. ;               Assumes 0 < CX <= 255
  20. ;
  21. ; Returns:      ES:DI   = address of quotient
  22. ;               DS:SI   = address of remainder
  23. ;
  24. ;               NOTE: Dividend is assumed to be twice as long
  25. ;               as the divisor.  Returned remainder and quotient 
  26. ;               are same size as divisor.
  27. ;
  28. ; Destroys:     AX (other registers preserved)
  29.  
  30. _TEXT   segment word public 'CODE'
  31.  
  32.         assume  cs:_TEXT
  33.  
  34.         public  mpdiv
  35. mpdiv   proc    near
  36.  
  37.         push    bx                      ; save registers        
  38.         push    cx
  39.         push    dx
  40.         push    si
  41.         push    di
  42.         push    bp
  43.  
  44.         mov     dx,cx                   ; save divisor length in DX
  45.  
  46.         mov     bp,cx                   ; BP will be outer loop 
  47.         shl     bp,1                    ; counter, set it to number
  48.         shl     bp,1                    ; of bits in divisor
  49.         shl     bp,1
  50.  
  51.         clc                             ; initially clear carry
  52.  
  53. mpdiv1: push    di                      ; save pointer to dividend
  54.         mov     cx,dx                   ; CX = bytes in dividend
  55.  
  56. mpdiv2: rcl     word ptr [di],1         ; shift carry flag into
  57.         inc     di                      ; low bit of quotient
  58.         inc     di                      ; shift high bit of dividend
  59.         loop    mpdiv2                  ; into carry flag
  60.  
  61.         pop     di                      ; restore pointer to dividend
  62.  
  63.         jnc     mpdiv5                  ; jump if high bit was clear
  64.  
  65. mpdiv3: push    si                      ; save pointer to divisor
  66.         push    di                      ; save pointer to dividend
  67.  
  68.         add     di,dx                   ; DI = addr high half of dividend
  69.         mov     cx,dx                   ; CX = bytes in divisor
  70.         clc                             ; initially clear carry
  71.  
  72. mpdiv4: mov     al,[si]                 ; subtract divisor from high
  73.         sbb     [di],al                 ; half of dividend
  74.         inc     si
  75.         inc     di
  76.         loop    mpdiv4
  77.  
  78.         pop     di                      ; restore pointer to dividend
  79.         pop     si                      ; restore pointer to divisor
  80.  
  81.         stc                             ; shift bit=1 into quotient
  82.         dec     bp                      ; all bits of answer generated?
  83.         jnz     mpdiv1                  ; no, loop
  84.         jmp     mpdiv7                  ; yes, go clean up and exit
  85.  
  86. mpdiv5: push    si                      ; save pointer to divisor
  87.         push    di                      ; save pointer to dividend
  88.  
  89.         add     di,dx                   ; point to high half of dividend
  90.         mov     cx,dx                   ; CX = bytes in divisor
  91.         clc                             ; initially clear carry
  92.  
  93. mpdiv6: mov     al,[di]                 ; high half of dividend > divisor?
  94.         sbb     al,[si]
  95.         inc     si
  96.         inc     di
  97.         loop    mpdiv6
  98.  
  99.         pop     di                      ; restore pointer to dividend
  100.         pop     si                      ; restore pointer to divisor
  101.  
  102.         jnc     mpdiv3                  ; jump, high dividend > divisor
  103.  
  104.         clc                             ; shift bit=0 into quotient
  105.         dec     bp                      ; all bits of answer generated?
  106.         jnz     mpdiv1                  ; no, loop again
  107.  
  108. mpdiv7: mov     cx,dx                   ; CX = bytes in quotient
  109.  
  110. mpdiv8: rcl     byte ptr [di],1         ; bring final bit into quotient
  111.         inc     di             
  112.         loop    mpdiv8         
  113.  
  114.         xchg    si,di                   ; copy remainder to final address
  115.         mov     cx,dx
  116.         rep movsb
  117.  
  118.         pop     bp                      ; restore registers
  119.         pop     di
  120.         pop     si
  121.         pop     dx
  122.         pop     cx
  123.         pop     bx
  124.         ret                             ; back to caller
  125.  
  126. mpdiv   endp
  127.  
  128. _TEXT   ends
  129.  
  130.         end
  131.  
  132.